﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data.SqlClient;
using System.Diagnostics;

//namespace ImmutableAnonymousTypes
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var rena = new { FirstName = "Rena", LastName = "Mody" };
//            // error - immutable 
//            //rena.FirstName = "Dena";
//            Console.WriteLine(rena);
//            Console.ReadLine();
//        }
//    }
//}

//namespace AnonymousTypeWithMethod
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            Func<string, string, string> Concat1 =
//                delegate(string first, string last)
//                {
//                    return last + ", " + first;
//                };

//            Func<Type, Object, string> Concat2 =
//                delegate(Type t, Object o)
//                {
//                    PropertyInfo[] info = t.GetProperties();
//                    return (string)info[1].GetValue(o, null) + ", " + (string)info[0].GetValue(o, null);
//                };

//            //var dena = new { FirstName = "Dena", LastName = "Swanson", Concat = Concat1 };
//            var dena = new { FirstName = "Dena", LastName = "Swanson", Concat = Concat2 };
//            //Console.WriteLine(dena.Concat(dena.FirstName, dena.LastName));
//            Console.WriteLine(dena.Concat(dena.GetType(), dena));
//            Console.ReadLine();
//        }
//    }
//}

//namespace AnonymousForLoop
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var fibonacci = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 };
//            for (var i = 0; i < fibonacci.Length; i++)
//                Console.WriteLine(fibonacci[i]);
//            Console.ReadLine();
//        }
//    }
//}

//namespace AnonymousForEachLoop
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var fibonacci = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 };
//            foreach (var i in fibonacci)
//            {
//                i = 1;
//            }
//            foreach (var fibo in fibonacci)
//                Console.WriteLine(fibo);
//            Console.ReadLine();
//        }
//    }
//}

//namespace AnonymousForEachLoopFromExpression
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var fibonacci = new int[] { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };
//            // uses LINQ query
//            foreach (var fibo in from f in fibonacci where f % 3 == 0 select f)
//                Console.WriteLine(fibo);
//            Console.ReadLine();
//        }
//    }
//}

//namespace AnonymousUsingStatement
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            string connectionString = "Data Source=ZYAN9\\NAMEDEXPRESS;Initial Catalog=Northwind;" + "Integrated Security=True";
//            using (var connection = new SqlConnection(connectionString))
//            {
//                connection.Open();
//                Console.WriteLine(connection.State);
//                Console.ReadLine();
//            }
//        }
//    }
//}

//namespace ReturnAnonymousTypeFromMethod
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var anon = GetAnonymous();
//            Type t = anon.GetType();
//            Console.WriteLine(t.GetProperty("Stock").GetValue(anon, null));
//            Console.ReadLine();
//        }

//        public static object GetAnonymous()
//        {
//            var stock = new { Stock = "MSFT", Price = "32.45" };
//            return stock;
//        }
//    }
//}

//namespace TestAnonymousTypeEquality
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var audioBook = new { Artist = "Bob Dylan", Song = "I Shall Be Released" };
//            var songBook1 = new { Artist = "Bob Dylan", Song = "I Shall Be Released" };
//            var songBook2 = new { Singer = "Bob Dylan", Song = "I Shall Be Released" };
//            var audioBook1 = new { Song = "I Shall Be Released", Artist = "Bob Dylan" };

//            if (audioBook.Equals(audioBook1))
//                Console.WriteLine("Equal");
//            else
//                Console.WriteLine("Not equal");
//            Console.ReadLine();
//        }
//    }
//}

//namespace AnonymousTypeWithQuery
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7 };
//            var all = from n in numbers orderby n descending select n;

//            foreach (var n in all)
//                Console.WriteLine(n);

//            var songs = new string[] { "Let it be", "I shall be released" };
//            var newType = from song in songs select new { Title = song };

//            foreach (var s in newType)
//                Console.WriteLine(s.Title);

//            Console.ReadLine();
//        }
//    }
//}

//namespace AnonymousMethod
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            // ctrl + c
//            Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);

//            // anonymous cancel delegate
//            Console.CancelKeyPress +=
//                delegate
//                {
//                    Console.WriteLine("Anonymous Cancel pressed!");
//                };

//            Console.ReadLine();
//        }

//        static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
//        {
//            Console.WriteLine("Ctrl + C is pressed!");
//        }
//    }
//}

//namespace AnonymousGenericDelegate
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            Func<long, long> Factorial =
//                delegate(long n)
//                {
//                    if (n == 1) return 1;
//                    long result = 1;
//                    for (int i = 2; i <= n; i++)
//                        result *= i;
//                    return result;
//                };

//            Console.WriteLine(Factorial(6L));
//            Console.ReadLine();
//        }
//    }
//}

namespace AnoymousGenericRecursiveDelegate
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<long, long> Factorial =
                delegate(long n)
                {
                    return n > 1 ?
                        n * (long)(new StackTrace().GetFrame(0).GetMethod().Invoke(null,new object[] {n-1}))
                        : n;
                };

            Console.WriteLine(Factorial(4));
            Console.ReadLine();
        }
    }
}
